# 这个文件中处理针对主单的条件添加
import json
import re

def build_pattern(rawList):
    patterns = []
    for x in rawList:
        if not x:
            continue
        # 将%和_转换为正则
        pattern = re.escape(x).replace(r'\%', '.*').replace(r'\_', '.')
        # 添加完整匹配边界
        pattern = '^' + pattern + '$'
        patterns.append(pattern)
    return '|'.join(patterns)

# 针对yearold
def genAge(ruleDatum, ruleAct, filterDatum, hsp_abbr):
    # 获取operator的值，是 gt, lt, gte, lte, eq
    operator = filterDatum['operator']
    if operator == 'gt':
        operSql = ">"
    elif operator == 'lt':
        operSql = "<"
    elif operator == 'gte':
        operSql = ">="
    elif operator == 'lte':
        operSql = "<="
    elif operator == 'eq':
        operSql = "="
    
    # 获取value值
    value = filterDatum['value']
    # 如果value是 True，则转变为1
    if value is True:
        value = 1

    """
    ============ 思路 ============
    1. 更新 va 表，如果没有item_time的，则从m表更新in_time进去
    2. 更新 va 表，将brdy更新到 va 的 date1 字段
    3. 删除 va 表中没有 item_time 的部分
    4. 查出 va 表中符合违规范围的（item_time - brdy） setl_id，放在 vb 表
    5. 删除 va 表中没有 vb 表的部分
    6. 更新 va 表中的related：使用时为 {} 周岁
    """

    sqlList = [
        # 清空临时表
        "TRUNCATE TABLE vlt_tmp_b",
        # 第1步
        f"""
            -- age，step1. 更新 va 表，如果没有item_time的，则从m表更新in_time进去
            MERGE INTO vlt_tmp_a va
            USING m ON (va.setl_id = m.setl_id)
            WHEN MATCHED THEN
                UPDATE SET va.item_time = COALESCE(va.item_time, m.in_time, m.out_time)
        """,
        # 第2步
        f"""
            -- age，step2. 更新 va 表，将brdy更新到 va 的 date1 字段
            MERGE INTO vlt_tmp_a va
            USING m ON (va.setl_id = m.setl_id)
            WHEN MATCHED THEN
                UPDATE SET va.date1 = m.brdy
            WHERE m.brdy IS NOT NULL
        """,
        # 第3步
        f"""
            -- age，step3. 删除 va 表中没有 item_time 或者没有 date1 的部分
            DELETE FROM vlt_tmp_a
            WHERE item_time IS NULL OR date1 IS NULL
        """,
        # 第4步
        f"""
            -- age，step4. 查出 va 表中符合违规范围的（item_time - brdy） setl_id，放在 vb 表
            INSERT INTO vlt_tmp_b vb (setl_id)
            SELECT setl_id
            FROM vlt_tmp_a va
            WHERE (va.item_time - va.date1)/365.25 {operSql} {value}
        """,
        # 第5步
        f"""
            -- age，step5. 删除 va 表中没有 vb 表的部分
            DELETE FROM vlt_tmp_a
            WHERE setl_id NOT IN (SELECT setl_id FROM vlt_tmp_b)
        """,
        # 第6步
        f"""
            -- age，step6. 更新 va 表中的related：使用时为 XX 周岁
            UPDATE vlt_tmp_a va
            SET va.related = NVL(va.related, '') || '项目使用时为 ' || ROUND((va.item_time - va.date1)/365.25,2) || ' 周岁。'
        """,
    ]

    return sqlList

def genDayOld(ruleDatum, ruleAct, filterDatum, hsp_abbr):
    # 获取operator的值，是 gt, lt, gte, lte, eq
    operator = filterDatum['operator']
    if operator == 'gt':
        operSql = ">"
    elif operator == 'lt':
        operSql = "<"
    elif operator == 'gte':
        operSql = ">="
    elif operator == 'lte':
        operSql = "<="
    elif operator == 'eq':
        operSql = "="

    # 获得value，值是一个值，里面是一个整数
    value = filterDatum['value']
    if not value:
        return []  # 如果没有天数条件，直接返回原始SQL
    # 如果value是 True，则转变为1
    if value is True:
        value = 1

    """
    ============ 思路 ============
    1. 查出 va 表中符合违规范围的（天数符合的） setl_id，放在 vb 表
    2. 删除 va 表中没有 vb 表的部分
    """

    sqlList = [
        # 清空临时表
        "TRUNCATE TABLE vlt_tmp_b",
        # 第1步
        f"""
            -- dayold，step1. 查出 va 表中符合违规范围的（天数符合的） setl_id，放在 vb 表
            INSERT INTO vlt_tmp_b vb (setl_id)
            SELECT setl_id
            FROM vlt_tmp_a va
            WHERE EXISTS (
                SELECT 1
                FROM m
                WHERE va.setl_id = m.setl_id AND m.j_dayold_in {operSql} {value} AND m.j_dayold_out {operSql} {value}
            )
        """,
        # 第2步
        f"""
            -- dayold，step2. 删除 va 表中没有 vb 表的部分
            DELETE FROM vlt_tmp_a va
            WHERE NOT EXISTS (select 1 from vlt_tmp_b vb where va.setl_id = vb.setl_id)
        """
    ]

    return sqlList

# 针对 medType
def genMedType(ruleDatum, ruleAct, filterDatum, hsp_abbr):
    # 获得value，值是一个列表，里面是 medType 可能的值
    value = filterDatum['value']
    # 获得 operator，值要么是 include，要么是 exclude
    operator = filterDatum['operator']
    if not value:
        return []  # 如果没有病种条件，直接返回原始SQL

    operKeepSql = ' NOT ' if operator == 'exclude' else ' '
    operDropSql = ' ' if operator == 'exclude' else ' NOT '

    """
    ============ 思路 ============
    1. 查出 va 表中符合违规范围的（medType符合的） setl_id，放在 vb 表
    2. 删除 va 表中没有 vb 表的部分
    """

    sqlList = [
        # 清空临时表
        "TRUNCATE TABLE vlt_tmp_b",
        # 第1步
        f"""
            -- medType，step1. 查出 va 表中符合违规范围的（medType符合的） setl_id，放在 vb 表
            INSERT INTO vlt_tmp_b vb (setl_id)
            SELECT DISTINCT va.setl_id
            FROM vlt_tmp_a va
            JOIN m ON va.setl_id = m.setl_id
            WHERE {operKeepSql} (
                {' OR '.join([f"m.med_type = '{vt}'" for vt in value])}
            )
        """,
        # 第2步
        f"""
            -- medType，step2. 删除 va 表中没有 vb 表的部分
            DELETE FROM vlt_tmp_a va
            WHERE NOT EXISTS (select 1 from vlt_tmp_b vb where va.setl_id = vb.setl_id)
        """
    ]

    return sqlList

# 针对hsp
def genHsp(ruleDatum, ruleAct, filterDatum, hsp_abbr):
    # 获得 hspList.json
    with open('hspList.json', 'r', encoding='utf-8') as f:
        hspList = json.load(f)
    # 获得 hsp_abbr所对应的hspInfo
    hspInfo = next((hsp for hsp in hspList if hsp['hsp_abbr'] == hsp_abbr), None)
    hspName = hspInfo['hsp_name'] if hspInfo else '未知医院'

    # 获得operator，值要么是 include，要么是 exclude
    operator = filterDatum['operator']

    # 获得value，值是一个列表，里面是带有 % 的字符串
    pattern = build_pattern(filterDatum['value'])
    # 判断 hspName 是否匹配 pattern
    isMatch = re.search(pattern, hspName, re.IGNORECASE) is not None

    # 如果operator是include，但是又不匹配，则sql添加一个绝对不成立的条件
    if operator == 'include' and not isMatch:
        # 永远不成立，删掉va的所有东西
        sqlList = [
            f"""
                -- hsp, include而且不匹配，删掉va表的所有数据
                DELETE FROM vlt_tmp_a
                WHERE hsp_abbr = '{hsp_abbr}'
            """
        ]
    elif operator == 'exclude' and isMatch:
        # 永远不成立，删掉va的所有东西
        sqlList = [
            f"""
                -- hsp, exclude而且匹配，删掉va表的所有数据
                DELETE FROM vlt_tmp_a
                WHERE hsp_abbr = '{hsp_abbr}'
            """
        ]
    else:
        # 如果是include且匹配，或者exclude且不匹配，则不添加任何条件
        sqlList = []

    return sqlList


# 针对gender
def genGender(ruleDatum, ruleAct, filterDatum, hsp_abbr):
    # 获得value，值是一个值，里面是 'm' 或 'f'
    value = filterDatum['value']
    if not value:
        return []  # 如果没有性别条件，直接返回原始SQL
    # 如果value是 True，则转变为1
    if value is True:
        value = 1

    """
    ============ 思路 ============
    1. 查出 va 表中符合违规范围的（性别符合的） setl_id，放在 vb 表
    2. 删除 va 表中没有 vb 表的部分
    3. 删除 va 表中 gend 不是 'm' 或 'f' 的部分
    """

    sqlList = [
        # 清空临时表
        "TRUNCATE TABLE vlt_tmp_b",
        # 第1步、第2步合并，直接删除 va 表中不符合性别范围的部分
        f"""
            -- gender，step1 and step2. 并删除 va 表不符合性别范围的部分
            DELETE FROM vlt_tmp_a va
            WHERE NOT EXISTS (
                SELECT 1
                FROM m
                WHERE va.setl_id = m.setl_id AND m.J_GEND = '{value}'
            )
        """,
        
        # 第3步
        f"""
            -- gender，step3. 删除 va 表中 gend 不是 'm' 或 'f' 的部分
            DELETE FROM vlt_tmp_a va
            WHERE NOT EXISTS (SELECT 1 FROM m WHERE va.setl_id = m.setl_id AND m.J_GEND IN ('m', 'f'))
        """
    ]

    return sqlList
    


# 针对period
def genPeriod(ruleDatum, ruleAct, filterDatum, hsp_abbr):
    # 获得operator，值是 gt, lt, gte, lte, eq
    operator = filterDatum['operator']
    if operator == 'gt':
        operSql = ">"
    elif operator == 'lt':
        operSql = "<"
    elif operator == 'gte':
        operSql = ">="
    elif operator == 'lte':
        operSql = "<="
    elif operator == 'eq':
        operSql = "="
    
    # 获得value
    value = filterDatum['value']
    # 如果value是 True，则转变为1
    if value is True:
        value = 1

    """
    ============ 思路 ============
    1. 查出 va 表中符合违规范围的（天数符合的） setl_id，放在 vb 表
    2. 删除 va 表中没有 vb 表的部分
    3. 删除 va 表中没有 period 的部分
    """

    sqlList = [
        # 清空临时表
        "TRUNCATE TABLE vlt_tmp_b",
        # 第1步
        f"""
            -- period，step1. 查出 va 表中符合违规范围的（天数符合的） setl_id，放在 vb 表
            INSERT INTO vlt_tmp_b vb (setl_id)
            SELECT setl_id
            FROM vlt_tmp_a va
            WHERE EXISTS (
                SELECT 1
                FROM m
                WHERE va.setl_id = m.setl_id AND m.period {operSql} {value}
            )
        """,
        # 第2步
        f"""
            -- period，step2. 删除 va 表中没有 vb 表的部分
            DELETE FROM vlt_tmp_a va
            WHERE NOT EXISTS (select 1 from vlt_tmp_b vb where va.setl_id = vb.setl_id)
        """,
        # 第3步
        f"""
            -- period，step3. 删除 va 表中没有 period 的部分
            DELETE FROM vlt_tmp_a va
            WHERE EXISTS (SELECT 1 FROM m WHERE va.setl_id = m.setl_id AND m.period IS NULL)
        """
    ]

    return sqlList
